package com.exwave.socialgame.model_wolfgame.controller;

import com.exwave.socialgame.jwt_token.Token;
import com.exwave.socialgame.model_wolfgame.Rooms;
import com.exwave.socialgame.model_wolfgame.service.RoomsService;
import com.exwave.socialgame.myutils.WolfGameUtils;
import com.exwave.socialgame.myutils.ParamsException;
import com.exwave.socialgame.myutils.RedisForWolfUtils;
import com.exwave.socialgame.myutils.ReturnUtils;
import com.exwave.socialgame.myutils.TimeUtils;
import com.exwave.socialgame.model_wolfgame.wolfdata.Player;
import com.exwave.socialgame.model_wolfgame.wolfdata.Room;
import com.exwave.socialgame.model_wolfgame.wolfdata.RoomConfigure;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * (Rooms)表控制层
 *
 * @author makejava
 * @since 2021-11-17 10:39:56
 */
@RestController
@RequestMapping("rooms")
public class RoomsController {
    /**
     * 服务对象
     */
    @Resource
    private RoomsService roomsService;

    @Resource
    private RedisForWolfUtils redisForWolfUtils;

    /**
     * 通过主键查询单条数据
     *
     * @param rId 主键
     */
    @GetMapping("selectOne")
    @Token.UserLoginToken
    @ApiOperation(value = "查询房间")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rId", value = "房间号", required = true, dataTypeClass = String.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object selectOne(Integer rId) {
        Room room = (Room) redisForWolfUtils.readRoom(rId);
        HashMap<String, Object> map = new HashMap<>();
        if (room != null) {
            map.put("room", room);
            return ReturnUtils.returnMap(200, "success", map);
        } else
            return ReturnUtils.returnMap(500, "Not found room");
    }

    /**
     * 创建房间
     *
     * @param rType 房间类型
     */
    @PostMapping("newRoom")
    @ApiOperation(value = "创建房间")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rType", value = "房间类型", required = true, dataTypeClass = Integer.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object newRoom(@RequestBody RoomConfigure roomConfigure, int rType) {
        Rooms rooms = new Rooms();
        rooms.setRtype(rType);
        rooms.setRtime(TimeUtils.getTime());
        rooms.setRmaster(roomConfigure.getPlayer().getUid());
        //房间汇总至MySQL
        try {
            this.roomsService.insert(rooms);
        } catch (ParamsException p) {
            return ReturnUtils.returnMap(p.getCode(), p.getMsg());
        } catch (Exception e) {
            return ReturnUtils.returnMap(500, "unknown error");
        }
        //创建房间至Redis
        Room room = new Room(rooms.getRid(), roomConfigure.getConfigure(), roomConfigure.getPlayer());
        room.setLocate_role(roomConfigure.getList()); //config三个参数全部用上，房主，配置数组，角色列表
        redisForWolfUtils.saveRoom(room); //保存房间信息至redis
        //返回创建的房间类
        HashMap<String, Object> map = new HashMap<>();
        map.put("room", room);
        return ReturnUtils.returnMap(200, "success", map);
    }

    /**
     * 查询房间列表
     *
     * @param limit  数量
     * @param offset 起始位置
     */
    @PostMapping("selectMore")
    @ApiOperation(value = "查询多个房间列表")
    @Token.UserLoginToken
    @ApiImplicitParams({
            @ApiImplicitParam(name = "limit", value = "查询数量", required = true, dataTypeClass = Integer.class, paramType = "query"),
            @ApiImplicitParam(name = "offset", value = "查询起始位置,0开始", required = true, dataTypeClass = Integer.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object selectMore(int offset, int limit) {
        List<Rooms> roomsList = null;
        try {
            roomsList = this.roomsService.queryAllByLimit(offset, limit);
        } catch (ParamsException p) {
            return ReturnUtils.returnMap(p.getCode(), p.getMsg());
        } catch (Exception e) {
            return ReturnUtils.returnMap(500, "unknown error");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("rooms", roomsList);
        return ReturnUtils.returnMap(200, "success", map);
    }


    /**
     * 销毁房间
     *
     * @param rId 房间ID
     */
    @PostMapping("deleteRoom")
    @ApiOperation("销毁房间")
    @Token.UserLoginToken
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rId", value = "房间Id", required = true, dataTypeClass = Integer.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object deleteRoom(int rId) {
        //房间列表中删除房间
        try {
            this.roomsService.deleteById(rId);
        } catch (ParamsException p) {
            return ReturnUtils.returnMap(p.getCode(), p.getMsg());
        } catch (Exception e) {
            return ReturnUtils.returnMap(500, "unknown error");
        }
        //删除redis缓存
        redisForWolfUtils.delRoom(rId);
        return ReturnUtils.returnMap(200, "success");
    }

    /**
     * 加入房间
     *
     * @param player 玩家
     * @param rId    房间ID
     */
    @PostMapping("addRoom")
    @ApiOperation("加入房间")
    @Token.UserLoginToken
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rId", value = "房间Id", required = true, dataTypeClass = Integer.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object addRoom(int rId, @RequestBody Player player) {
        Room room = redisForWolfUtils.readRoom(rId);
        if (room == null)
            return ReturnUtils.returnMap(500, "Not Found Room");
        else {
            int location = player.getNum();
            if (location < 0 || location > 12)
                return ReturnUtils.returnMap(500, "Error location");
            room.addRoom(player);//玩家入座
            redisForWolfUtils.saveRoom(room); //更新缓存
            HashMap<String, Object> map = new HashMap<>();
            map.put("room", room);
            return ReturnUtils.returnMap(200, "success", map);
        }
    }

    /**
     * 轮询实现房间配置传递；
     *
     * @param rId 房间ID
     * @return Room 房间json
     */
    @PostMapping("updateRoom")
    @ApiOperation(value = "轮询更新房间")
    @Token.UserLoginToken
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rId", value = "房间号（Int）", required = true, dataTypeClass = Integer.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object updateRoom(int rId) {
        Room room = redisForWolfUtils.readRoom(rId);
        if (room == null) {
            return ReturnUtils.returnMap(500, "Not such a Room");
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("room", room);
            return ReturnUtils.returnMap(200, "success", map);
        }
    }


    /**
     * 本地上传房间覆盖
     *
     * @param room 房间
     * @return Object
     */
    @PostMapping("replaceRoom")
    @ApiOperation(value = "房主更新房间状态")
    @Token.UserLoginToken
    @ApiImplicitParams({
            @ApiImplicitParam(name = "room", value = "房间类", required = true, dataTypeClass = Room.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "Token", required = true, dataTypeClass = String.class, paramType = "header")
    })
    public Object replaceRoom(Room room) {
        redisForWolfUtils.saveRoom(room);
        return WolfGameUtils.returnSuccess();
    }
}